/**
 @file ctc_stats_cli.c

 @date 2020-08-30

 @version v2.0

---file comments----
*/

/****************************************************************
 *
 * Header Files
 *
 ***************************************************************/
#include "sal.h"
#include "ctc_cli.h"
#include "ctc_cli_common.h"
#include "api/include/ctcs_api.h"
#include "ctc_common.h"
#include "ctc_stats.h"
#include "ctc_asw_common.h"
#include "ctc_stats_cli.h"

#define CTC_STATS_CLI_PRINT(str, pktcnt, byte, mode)                                              \
    do                                                                                            \
    {                                                                                             \
        if (mode == 0)                                                                            \
        {                                                                                         \
            ret = pktcnt ? ctc_cli_out("%-30s%-22"PRIu64"%-22s\n", str, pktcnt, "-") : 0;         \
        }                                                                                         \
        else if (mode == 1)                                                                       \
        {                                                                                         \
            ret = pktcnt ? ctc_cli_out("%-30s%-22"PRIu64"%-22"PRIu64"\n", str, pktcnt, byte) : 0; \
        }                                                                                         \
        else if (mode == 2)                                                                       \
        {                                                                                         \
            ctc_cli_out("%-30s%-22"PRIu64"%-22s\n", str, pktcnt, "-");                            \
        }                                                                                         \
        else                                                                                      \
        {                                                                                         \
            ctc_cli_out("%-30s%-22"PRIu64"%-22"PRIu64"\n", str, pktcnt, byte);                    \
        }                                                                                         \
    }while(0)

int32
ctc_asw_stats_show_mac_stats(ctc_vti_t* vty, uint16 gport, ctc_mac_stats_dir_t dir, ctc_mac_stats_t* p_stats, uint8 cli_mode)
{
    int32 ret = 0;
    uint8 mode = (cli_mode ? 2 : 0);
    ctc_mac_stats_t stats_tmp;
    uint8 hd_print = 0;
    uint64 not_care_bytes = 0;

    sal_memset(&stats_tmp, 0, sizeof(stats_tmp));

    if (sal_memcmp(&(p_stats->u), &stats_tmp.u, sizeof(stats_tmp.u)) || cli_mode)
    {
        ctc_cli_out("GPort 0x%04x, %-20s\n", gport, (CTC_STATS_MAC_STATS_RX == dir) ? "Mac Receive:" : "Mac Transmit:");
        ctc_cli_out("-------------------------------------------------------------------\n");
        ctc_cli_out("%-30s%-22s%-22s\n", "Type", "PktCnt", "Byte");
        ctc_cli_out("-------------------------------------------------------------------\n");
        hd_print = 1;
    }
    if (CTC_STATS_MAC_STATS_RX == dir)
    {
        if ((CTC_STATS_MODE_PLUS == p_stats->stats_mode))
        {
            CTC_STATS_CLI_PRINT("all receive       (total)",p_stats->u.stats_plus.stats.rx_stats_plus.all_pkts,p_stats->u.stats_plus.stats.rx_stats_plus.all_octets, (mode + 1));
            CTC_STATS_CLI_PRINT("unicast           (total)",p_stats->u.stats_plus.stats.rx_stats_plus.ucast_pkts,     not_care_bytes, mode);
            CTC_STATS_CLI_PRINT("multicast         (total)",p_stats->u.stats_plus.stats.rx_stats_plus.mcast_pkts,     not_care_bytes, mode);
            CTC_STATS_CLI_PRINT("broadcast         (total)",p_stats->u.stats_plus.stats.rx_stats_plus.bcast_pkts,     not_care_bytes, mode);
            CTC_STATS_CLI_PRINT("undersize         (total)",p_stats->u.stats_plus.stats.rx_stats_plus.runts_pkts,     not_care_bytes, mode);
            CTC_STATS_CLI_PRINT("oversize          (total)",p_stats->u.stats_plus.stats.rx_stats_plus.giants_pkts,    not_care_bytes, mode);
            CTC_STATS_CLI_PRINT("fcs erorr         (total)",p_stats->u.stats_plus.stats.rx_stats_plus.crc_pkts,       not_care_bytes, mode);
            CTC_STATS_CLI_PRINT("pause             (total)",p_stats->u.stats_plus.stats.rx_stats_plus.pause_pkts,     not_care_bytes, mode);
            CTC_STATS_CLI_PRINT("fragment          (total)",p_stats->u.stats_plus.stats.rx_stats_plus.fragments_pkts, not_care_bytes, mode);
            CTC_STATS_CLI_PRINT("jabber            (total)",p_stats->u.stats_plus.stats.rx_stats_plus.jabber_pkts,    not_care_bytes, mode);
            CTC_STATS_CLI_PRINT("jumbo             (total)",p_stats->u.stats_plus.stats.rx_stats_plus.jumbo_events,   not_care_bytes, mode);
        }
        if ((CTC_STATS_MODE_DETAIL == p_stats->stats_mode))
        {
            CTC_STATS_CLI_PRINT("good unicast",p_stats->u.stats_detail.stats.rx_stats.good_ucast_pkts, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("good multicast",p_stats->u.stats_detail.stats.rx_stats.good_mcast_pkts, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("good broadcast",p_stats->u.stats_detail.stats.rx_stats.good_bcast_pkts, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("good pause",p_stats->u.stats_detail.stats.rx_stats.good_pause_pkts, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("fcs error",p_stats->u.stats_detail.stats.rx_stats.fcs_error_pkts, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("mac overrun packets",p_stats->u.stats_detail.stats.rx_stats.mac_overrun_pkts, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("good oversize",p_stats->u.stats_detail.stats.rx_stats.good_oversize_pkts, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("good undersize",p_stats->u.stats_detail.stats.rx_stats.good_undersize_pkts, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("60B~63B",p_stats->u.stats_detail.stats.rx_stats.good_63_pkts, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("64B",p_stats->u.stats_detail.stats.rx_stats.pkts_64, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("65B~127B",p_stats->u.stats_detail.stats.rx_stats.pkts_65_to_127, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("128B~255B",p_stats->u.stats_detail.stats.rx_stats.pkts_128_to_255, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("256B~511B",p_stats->u.stats_detail.stats.rx_stats.pkts_256_to_511, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("512B~1023B",p_stats->u.stats_detail.stats.rx_stats.pkts_512_to_1023, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("1024B~max",p_stats->u.stats_detail.stats.rx_stats.pkts_1024_to_1518, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("good jumbo",p_stats->u.stats_detail.stats.rx_stats.good_jumbo_pkts, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("bad jumbo",p_stats->u.stats_detail.stats.rx_stats.bad_jumbo_pkts, not_care_bytes, (mode + 1));
        }
    }
    else
    {
        if ((CTC_STATS_MODE_PLUS ==p_stats->stats_mode))
        {
            CTC_STATS_CLI_PRINT("all transmit (total)",p_stats->u.stats_plus.stats.tx_stats_plus.all_pkts,p_stats->u.stats_plus.stats.tx_stats_plus.all_octets, (mode + 1));
            CTC_STATS_CLI_PRINT("unicast      (total)",p_stats->u.stats_plus.stats.tx_stats_plus.ucast_pkts,     not_care_bytes, mode);
            CTC_STATS_CLI_PRINT("multicast    (total)",p_stats->u.stats_plus.stats.tx_stats_plus.mcast_pkts,     not_care_bytes, mode);
            CTC_STATS_CLI_PRINT("broadcast    (total)",p_stats->u.stats_plus.stats.tx_stats_plus.bcast_pkts,     not_care_bytes, mode);
            CTC_STATS_CLI_PRINT("jumbo        (total)",p_stats->u.stats_plus.stats.tx_stats_plus.jumbo_events,   not_care_bytes, mode);
        }
        if ((CTC_STATS_MODE_DETAIL ==p_stats->stats_mode))
        {
            CTC_STATS_CLI_PRINT("good unicast",p_stats->u.stats_detail.stats.tx_stats.good_ucast_pkts, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("good multicast",p_stats->u.stats_detail.stats.tx_stats.good_mcast_pkts, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("good broadcast",p_stats->u.stats_detail.stats.tx_stats.good_bcast_pkts, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("good pause",p_stats->u.stats_detail.stats.tx_stats.good_pause_pkts, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("60B~63B",p_stats->u.stats_detail.stats.tx_stats.pkts_63, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("64B",p_stats->u.stats_detail.stats.tx_stats.pkts_64, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("65B~127B",p_stats->u.stats_detail.stats.tx_stats.pkts_65_to_127, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("128B~255B",p_stats->u.stats_detail.stats.tx_stats.pkts_128_to_255, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("256B~511B",p_stats->u.stats_detail.stats.tx_stats.pkts_256_to_511, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("512B~1023B",p_stats->u.stats_detail.stats.tx_stats.pkts_512_to_1023, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("1024B~max",p_stats->u.stats_detail.stats.tx_stats.pkts_1024_to_1518, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("oversize",p_stats->u.stats_detail.stats.tx_stats.oversize_pkts, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("jumbo",p_stats->u.stats_detail.stats.tx_stats.jumbo_pkts, not_care_bytes, (mode + 1));
            CTC_STATS_CLI_PRINT("fcs error",p_stats->u.stats_detail.stats.tx_stats.fcs_error_pkts, not_care_bytes, (mode + 1));
        }
    }
    if (hd_print)
    {
        ctc_cli_out("-------------------------------------------------------------------\n");
        ctc_cli_out("\n");
    }
    return ret;
}

CTC_CLI(ctc_cli_asw_stats_show_mac,
        ctc_cli_asw_stats_show_mac_cmd,
        "show stats (mac-rx | mac-tx | mac-all) (port GPHYPORT_ID (end-port END_PORT | ) | all) (mode (plus | detail) | )",
        CTC_CLI_SHOW_STR,
        CTC_CLI_STATS_STR,
        "Mac reception statistics",
        "Mac transmission statistics",
        "Mac reception and transmission statistics",
        CTC_CLI_GPORT_DESC,
        CTC_CLI_GPHYPORT_ID_DESC,
        "End GPort",
        CTC_CLI_GPHYPORT_ID_DESC,
        "All port",
        "Statistics information from mode",
        "Read info from Asic",
        "Read info from Table")
{
    int32 ret = 0;
    uint16 gport_id = 0;
    uint16 gport_start = 0;
    uint16 gport_end = 0;
    uint16 lport_start = 0;
    uint16 lport_end = 0;
    uint16 loop = 0;
    uint8 loop_dir = 0;
    uint8 loop_dir_start = 0;
    uint8 loop_dir_end = 0;
    uint8 index = 0;
    ctc_mac_stats_t* p_stats = NULL;
    ctc_mac_stats_dir_t dir = CTC_STATS_MAC_STATS_MAX;
    uint64 stats_temp[4] = {0};
    uint8 cli_mode = 1;
    uint8 stats_mode = 0;

    stats_mode = CTC_STATS_MODE_DETAIL;

    index = CTC_CLI_GET_ARGC_INDEX("mac-rx");
    if (0xFF != index)
    {
        dir = CTC_STATS_MAC_STATS_RX;
    }

    index = CTC_CLI_GET_ARGC_INDEX("mac-tx");
    if (0xFF != index)
    {
        dir = CTC_STATS_MAC_STATS_TX;
    }

    index = CTC_CLI_GET_ARGC_INDEX("plus");
    if (0xFF != index)
    {
        stats_mode = CTC_STATS_MODE_PLUS;
    }

    index = CTC_CLI_GET_ARGC_INDEX("detail");
    if (0xFF != index)
    {
        stats_mode = CTC_STATS_MODE_DETAIL;
    }

    index = CTC_CLI_GET_ARGC_INDEX("all");
    if (0xFF != index)
    {
        lport_start = 0;
        lport_end = CTC_ASW_MAX_PHY_PORT;
        cli_mode = 0;
    }
    else
    {
        index = CTC_CLI_GET_ARGC_INDEX("port");
        if (0xFF != index)
        {
            CTC_CLI_GET_UINT16_RANGE("gport_start", gport_start, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
            gport_end = gport_start;
        }
        index = CTC_CLI_GET_ARGC_INDEX("end-port");
        if (0xFF != index)
        {
            CTC_CLI_GET_UINT16_RANGE("gport_end", gport_end, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
            cli_mode = 0;
        }

        lport_start = gport_start;
        lport_end = gport_end;
    }

    if (dir == CTC_STATS_MAC_STATS_MAX)
    {
        ctc_cli_out("\n");
        ctc_cli_out("Show Mac Stats Briefly\n");
        ctc_cli_out("-------------------------------------------------------------------------------------\n");
        ctc_cli_out("%-8s%-21s%-21s%-21s%-21s\n", "Gport", "RxCnt", "RxByte", "TxCnt", "TxByte");
        ctc_cli_out("-------------------------------------------------------------------------------------\n");
        loop_dir_start = CTC_STATS_MAC_STATS_RX;
        loop_dir_end   = CTC_STATS_MAC_STATS_TX;

        stats_mode = CTC_STATS_MODE_PLUS;
    }
    else
    {
        loop_dir_start = dir;
        loop_dir_end = dir;
    }

    p_stats = (ctc_mac_stats_t*)mem_malloc(MEM_CLI_MODULE, sizeof(ctc_mac_stats_t));
    if (NULL == p_stats)
    {
        return CTC_E_NO_MEMORY;
    }
    sal_memset(p_stats, 0, sizeof(ctc_mac_stats_t));
    p_stats->stats_mode = stats_mode;
    for (loop = lport_start; loop <= lport_end; loop++)
    {
        gport_id = loop;
        for (loop_dir = loop_dir_start; loop_dir <= loop_dir_end; loop_dir++)
        {
            ret = ctcs_stats_get_mac_stats(g_api_lchip, gport_id, loop_dir, p_stats);
            if (ret < 0)
            {
                continue;
            }
            if (loop_dir == CTC_STATS_MAC_STATS_RX)
            {
                stats_temp[0] = p_stats->u.stats_plus.stats.rx_stats_plus.all_pkts;
                stats_temp[1] = p_stats->u.stats_plus.stats.rx_stats_plus.all_octets;
            }
            if (loop_dir == CTC_STATS_MAC_STATS_TX)
            {
                stats_temp[2] = p_stats->u.stats_plus.stats.tx_stats_plus.all_pkts;
                stats_temp[3] = p_stats->u.stats_plus.stats.tx_stats_plus.all_octets;
            }
            if (dir == CTC_STATS_MAC_STATS_MAX)
            {
                if (loop_dir == CTC_STATS_MAC_STATS_TX)
                {
                    ctc_cli_out("0x%04x  %-21"PRIu64"%-21"PRIu64"%-21"PRIu64"%-21"PRIu64"\n", gport_id, stats_temp[0], stats_temp[1], stats_temp[2], stats_temp[3]);
                }
            }
            else
            {
                ctc_asw_stats_show_mac_stats(vty, gport_id, loop_dir, p_stats, cli_mode);
            }
        }

    }
    if (dir == CTC_STATS_MAC_STATS_MAX)
    {
        ctc_cli_out("-------------------------------------------------------------------------------------\n");
        ctc_cli_out("\n");
    }

    mem_free(p_stats);
    return CLI_SUCCESS;
}

CTC_CLI(ctc_cli_asw_stats_reset_mac,
        ctc_cli_asw_stats_reset_mac_cmd,
        "clear stats ( mac-rx | mac-tx | mac-all) (port GPHYPORT_ID (end-port GPHYPORT_ID|) | all)",
        CTC_CLI_CLEAR_STR,
        CTC_CLI_STATS_STR,
        "Mac reception statistics",
        "Mac transmission statistics",
        "Mac reception and transmission statistics",
        CTC_CLI_GPORT_DESC,
        CTC_CLI_GPHYPORT_ID_DESC,
        "End GPort",
        CTC_CLI_GPHYPORT_ID_DESC,
        "All port")
{
    int32 ret = 0;
    ctc_mac_stats_dir_t dir = CTC_STATS_MAC_STATS_MAX;
    uint32 max_port_num_per_chip = 29;
    uint16 loop = 0;
    uint8 loop_dir = 0;
    uint8 loop_dir_start = 0;
    uint8 loop_dir_end = 0;
    uint8 index = 0;
    uint16 gport_start = 0;
    uint16 gport_end = 0;


    if (CLI_CLI_STR_EQUAL("mac-rx", 0))
    {
        dir = CTC_STATS_MAC_STATS_RX;
    }
    else if (CLI_CLI_STR_EQUAL("mac-tx", 0))
    {
        dir = CTC_STATS_MAC_STATS_TX;
    }

    index = CTC_CLI_GET_ARGC_INDEX("all");
    if (0xFF != index)
    {
        gport_start = 0;
        gport_end = max_port_num_per_chip - 1;
    }
    else
    {
        index = CTC_CLI_GET_ARGC_INDEX("port");
        if (0xFF != index)
        {
            CTC_CLI_GET_UINT16_RANGE("gport_start", gport_start, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
            gport_end = gport_start;
        }
        index = CTC_CLI_GET_ARGC_INDEX("end-port");
        if (0xFF != index)
        {
            CTC_CLI_GET_UINT16_RANGE("gport_end", gport_end, argv[index + 1], 0, CTC_MAX_UINT16_VALUE);
        }
    }

    if (dir == CTC_STATS_MAC_STATS_MAX)
    {
        loop_dir_start = CTC_STATS_MAC_STATS_RX;
        loop_dir_end = CTC_STATS_MAC_STATS_TX;
    }
    else
    {
        loop_dir_start = dir;
        loop_dir_end = dir;
    }

    for (loop_dir = loop_dir_start; loop_dir <= loop_dir_end; loop_dir++)
    {
        for (loop = gport_start; loop <= gport_end; loop++)
        {
            ret = ctcs_stats_clear_mac_stats(g_api_lchip, loop, loop_dir);
            if (ret < 0)
            {
                continue;
            }
        }
    }

    return CLI_SUCCESS;
}

CTC_CLI(ctc_cli_asw_stats_set_mtu2_packet_length,
        ctc_cli_asw_stats_set_mtu2_packet_length_cmd,
        "stats mtu2-pkt-length port GPHYPORT_ID length PKT_LENGTH",
        CTC_CLI_STATS_STR,
        "MTU2 packet length,packet length larger than this consider as jumbo packet.Default is 1536B",
        CTC_CLI_GPORT_DESC,
        CTC_CLI_GPHYPORT_ID_DESC,
        "Packet length",
        "Packet mtu2 length")
{
    int32 ret = 0;
    uint16 length = 0;
    uint16 gport_id = 0;
    ctc_mac_stats_prop_type_t mac_stats_prop_type = CTC_STATS_MAC_STATS_PROP_MAX;
    ctc_mac_stats_property_t prop_data;

    mac_stats_prop_type = CTC_STATS_PACKET_LENGTH_MTU2;
    sal_memset(&prop_data, 0, sizeof(ctc_mac_stats_property_t));

    CTC_CLI_GET_UINT16_RANGE("gport", gport_id, argv[0], 0, CTC_MAX_UINT16_VALUE);
    CTC_CLI_GET_UINT16_RANGE("length", length, argv[1], 0, CTC_MAX_UINT16_VALUE);


    prop_data.data.length = length;
    ret = ctcs_stats_set_mac_stats_cfg(g_api_lchip, gport_id, mac_stats_prop_type, prop_data);
    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return CLI_SUCCESS;
}

CTC_CLI(ctc_cli_asw_stats_show_mac_cfg,
        ctc_cli_asw_stats_show_mac_cfg_cmd,
        "show stats mtu2-pkt-length  port GPHYPORT_ID",
        CTC_CLI_SHOW_STR,
        CTC_CLI_STATS_STR,
        "MTU2 packet length,packet length larger than this consider as jumbo packet.Default is 1536B,must greater than MTU1",
        CTC_CLI_GPORT_DESC,
        CTC_CLI_GPHYPORT_ID_DESC)
{
    int32 ret = 0;
    uint16 gport_id = 0;
    ctc_mac_stats_prop_type_t mac_stats_prop_type = CTC_STATS_MAC_STATS_PROP_MAX;
    ctc_mac_stats_property_t prop_data;

    sal_memset(&prop_data, 0, sizeof(ctc_mac_stats_property_t));
    mac_stats_prop_type = CTC_STATS_PACKET_LENGTH_MTU2;

    CTC_CLI_GET_UINT16_RANGE("gport", gport_id, argv[0], 0, CTC_MAX_UINT16_VALUE);

    ret = ctcs_stats_get_mac_stats_cfg(g_api_lchip, gport_id, mac_stats_prop_type, &prop_data);
    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    ctc_cli_out("===============================\n");
    ctc_cli_out("MTU2 packet length:       %u\n", prop_data.data.length);
    ctc_cli_out("===============================\n");

    return CLI_SUCCESS;
}


CTC_CLI(ctc_cli_asw_stats_drop_log,
        ctc_cli_asw_stats_drop_log_cmd,
        "stats drop-packet flow (enable | disable)",
        CTC_CLI_STATS_STR,
        "drop paket",
        "flow",
        "enable log drop",
        "disable log drop")
{
    int32 ret = 0;
    uint8 index = 0xFF;
    ctc_stats_discard_t bitmap = 0;
    bool enable = FALSE;

    bitmap = bitmap | CTC_STATS_FLOW_DISCARD_STATS;
    index = 0xFF;
    index = CTC_CLI_GET_ARGC_INDEX("enable");
    if (index != 0xFF)
    {
        enable = TRUE;
    }

    index = 0xFF;
    index = CTC_CLI_GET_ARGC_INDEX("disable");
    if (index != 0xFF)
    {
        enable = FALSE;
    }

    ret = ctcs_stats_set_drop_packet_stats_en(g_api_lchip, bitmap, enable);
    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return CLI_SUCCESS;
}

CTC_CLI(ctc_cli_asw_stats_show_drop_log,
        ctc_cli_asw_stats_show_drop_log_cmd,
        "show stats port GPHYPORT_ID drop-packet flow",
        CTC_CLI_SHOW_STR,
        CTC_CLI_STATS_STR,
        CTC_CLI_GPORT_DESC,
        CTC_CLI_GPHYPORT_ID_DESC,
        "drop paket",
        "flow")
{
    int32 ret = 0;
    ctc_stats_discard_t bitmap = 0;
    bool enable;
    char str[20];

    bitmap = bitmap | CTC_STATS_FLOW_DISCARD_STATS;
    sal_memcpy(str, "flow-stats", sizeof("flow-stats"));

    ret = ctcs_stats_get_drop_packet_stats_en(g_api_lchip, bitmap, &enable);
    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    ctc_cli_out("stats discard pkt type:%s, enable:%d\n", str, enable);

    return CLI_SUCCESS;
}

CTC_CLI(ctc_cli_asw_stats_show_stats,
        ctc_cli_asw_stats_show_stats_cmd,
        "show stats stats-id STATS_ID ",
        CTC_CLI_SHOW_STR,
        CTC_CLI_STATS_STR,
        CTC_CLI_STATS_ID_DESC,
        CTC_CLI_STATS_ID_VAL)
{
    int32 ret = 0;
    uint32 stats_id = 0;
    ctc_stats_basic_t p_stats[3];

    sal_memset(&p_stats, 0, sizeof(p_stats));
    CTC_CLI_GET_UINT32_RANGE("stats id", stats_id, argv[0], 0, CTC_MAX_UINT32_VALUE);

    ret = ctcs_stats_get_stats(g_api_lchip, stats_id, p_stats);
    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    ctc_cli_out("packets: %"PRId64", bytes: %"PRId64"\n", p_stats[0].packet_count, p_stats[0].byte_count);

    return CLI_SUCCESS;
}

CTC_CLI(ctc_cli_asw_stats_clear_stats,
        ctc_cli_asw_stats_clear_stats_cmd,
        "clear stats STATS_ID",
        CTC_CLI_CLEAR_STR,
        CTC_CLI_STATS_STR,
        CTC_CLI_STATS_ID_VAL)
{
    int32 ret = 0;
    uint32 stats_id = 0;

    CTC_CLI_GET_UINT32_RANGE("stats id", stats_id, argv[0], 0, CTC_MAX_UINT32_VALUE);

    ret = ctcs_stats_clear_stats(g_api_lchip, stats_id);
    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return CLI_SUCCESS;
}

int32
ctc_asw_stats_cli_init(uint8 cli_tree_mode)
{
    install_element(cli_tree_mode, &ctc_cli_asw_stats_show_mac_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_stats_reset_mac_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_stats_set_mtu2_packet_length_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_stats_show_mac_cfg_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_stats_drop_log_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_stats_show_drop_log_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_stats_show_stats_cmd);
    install_element(cli_tree_mode, &ctc_cli_asw_stats_clear_stats_cmd);

    return CLI_SUCCESS;
}

